﻿namespace UnityEditor
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    internal class AnimationPropertyDiff
    {
        private const float epsilon = 1E-05f;

        public static PropertyState[] CompareState(PropertyState[] lhs, PropertyState[] rhs)
        {
            if ((lhs == null) || (rhs == null))
            {
                return null;
            }
            if (lhs.Length != rhs.Length)
            {
                return null;
            }
            List<PropertyState> list = new List<PropertyState>();
            for (int i = 0; i < lhs.Length; i++)
            {
                if (((lhs[i].target == rhs[i].target) && (lhs[i].propertyName == rhs[i].propertyName)) && (lhs[i].path == rhs[i].path))
                {
                    if (Mathf.Abs((float) (lhs[i].value - rhs[i].value)) > 1E-05f)
                    {
                        list.Add(rhs[i]);
                    }
                }
                else
                {
                    return null;
                }
            }
            return list.ToArray();
        }

        public static PropertyState[] ExtractCurrentState(GameObject go)
        {
            List<PropertyState> properties = new List<PropertyState>();
            ExtractCurrentStateRecurse(go.transform, go.transform, properties);
            return properties.ToArray();
        }

        public static void ExtractCurrentStateRecurse(Transform transform, Transform root, List<PropertyState> properties)
        {
            IEnumerator enumerator = transform.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    Transform current = (Transform) enumerator.Current;
                    ExtractCurrentStateRecurse(current, root, properties);
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable == null)
                {
                }
                disposable.Dispose();
            }
            string str = AnimationUtility.CalculateTransformPath(transform, root);
            AnimationClipCurveData[] animatableProperties = AnimationUtility.GetAnimatableProperties(transform.gameObject);
            for (int i = 0; i < animatableProperties.Length; i++)
            {
                float num2;
                if (AnimationUtility.GetFloatValue(transform.gameObject, animatableProperties[i].path, animatableProperties[i].type, animatableProperties[i].propertyName, out num2))
                {
                    PropertyState item = new PropertyState {
                        target = animatableProperties[i].target,
                        propertyName = animatableProperties[i].propertyName,
                        path = str,
                        type = animatableProperties[i].type,
                        value = num2
                    };
                    properties.Add(item);
                }
            }
        }

        public static bool RecordModifiedProperties(PropertyState[] modified, GameObject root, AnimationClip clip, float currentTime, float timeFloor, float timeCeiling)
        {
            if (modified.Length == 0)
            {
                return false;
            }
            Undo.RegisterUndo(clip, "Auto Record Key", -1);
            List<int> list = new List<int>();
            for (int i = 0; i < modified.Length; i++)
            {
                PropertyState state = modified[i];
                if (state.type == typeof(Transform))
                {
                    int curveGroupID = CurveUtility.GetCurveGroupID(clip, state.GetCurveData());
                    if (!list.Contains(curveGroupID))
                    {
                        list.Add(curveGroupID);
                        bool flag = false;
                        string str = state.propertyName.Substring(0, state.propertyName.Length - 1);
                        if (state.propertyName.StartsWith("m_LocalR"))
                        {
                            if (((AnimationUtility.GetEditorCurve(clip, state.path, state.type, "localEulerAngles.x") != null) || (AnimationUtility.GetEditorCurve(clip, state.path, state.type, "localEulerAngles.y") != null)) || (AnimationUtility.GetEditorCurve(clip, state.path, state.type, "localEulerAngles.z") != null))
                            {
                                str = "localEulerAngles.";
                                flag = true;
                            }
                            else
                            {
                                str = "localEulerAnglesBaked.";
                            }
                        }
                        for (int j = 0; j < 3; j++)
                        {
                            float num4;
                            state.propertyName = str + ((j != 0) ? ((j != 1) ? "z" : "y") : "x");
                            CurveUtility.GetFloatValue(root, state.path, state.type, state.propertyName, out num4);
                            CurveRenderer curveRenderer = CurveUtility.GetCurveRenderer(clip, state.GetCurveData());
                            CurveUtility.AddOrReplaceKey(curveRenderer, currentTime, num4, timeFloor, timeCeiling);
                            AnimationUtility.SetEditorCurve(clip, state.path, state.type, state.propertyName, curveRenderer.GetCurve());
                            if (flag)
                            {
                                ((EulerCurveRenderer) curveRenderer).SetQuaternionsDirty();
                            }
                        }
                    }
                }
                else
                {
                    CurveRenderer renderer = CurveUtility.GetCurveRenderer(clip, state.GetCurveData());
                    CurveUtility.AddOrReplaceKey(renderer, currentTime, state.value, timeFloor, timeCeiling);
                    AnimationUtility.SetEditorCurve(clip, state.path, state.type, state.propertyName, renderer.GetCurve());
                }
            }
            return true;
        }

        [Serializable]
        internal class PropertyState
        {
            public string path;
            public string propertyName;
            public UnityEngine.Object target;
            public System.Type type;
            public float value;

            public AnimationClipCurveData GetCurveData()
            {
                return new AnimationClipCurveData { path = this.path, propertyName = this.propertyName, target = this.target, type = this.type };
            }
        }
    }
}

